package yxy.game.pm2.module;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import yxy.apple.util.RandomUtility;
import yxy.apple.util.RandomUtility.Weight;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.equipdata;
import yxy.cherry.data.bean.herodata;
import yxy.cherry.data.bean.randomdrop;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.Item;
import yxy.game.pm2.bean.currency.Currencies;
import yxy.game.pm2.bean.currency.CurrencyNotEnoughException;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.message.PackageMessage;
import yxy.game.pm2.message.PackageMessage.Package.Builder;
import yxy.game.pm2.module.hero.HeroHandle;

public class PackageHandle {

    public Collection<Currency> getItems(String playerCode, CurrencyType type) throws RedisException {
        switch (type) {
            case CT_物品:
            case CT_装备:
            case CT_碎片:
                return Item.all(playerCode, type).values();
//		case CT_魂玉:
//			break;
            default:
                return null;
        }
    }

    public Builder getPackage(String playerCode, CurrencyType type) throws Exception {
        Collection<Currency> currencies = getItems(playerCode, type);
        Builder pack = PackageMessage.Package.newBuilder();
        for (Currency currency : currencies) {
            if (currency.getNumber() <= 0) {
                continue;
            }
            PackageMessage.Item.Builder item = PackageMessage.Item.newBuilder();
            item.setDataId(currency.getDataId());
            item.setNumber(currency.getNumber());
            pack.addItems(item);
        }
        pack.setType(type.getNumber());
        return pack;
    }

    /**
     * 获取装备
     */
    public Builder getEquipPackageByPos(String playerCode, int equippos) throws Exception {
        Map<String, equipdata> alldata = DataCenter.getAllData(equipdata.class);
        Collection<Currency> currencies = getItems(playerCode, CurrencyType.CT_装备);
        Builder pack = PackageMessage.Package.newBuilder();
        for (Currency currency : currencies) {
            if (currency.getNumber() <= 0) {
                continue;
            }
            equipdata data = alldata.get(String.valueOf(currency.getDataId()));
            if (data == null || data.getPosition() != equippos) {
                continue;
            }
            PackageMessage.Item.Builder item = PackageMessage.Item.newBuilder();
            item.setDataId(currency.getDataId());
            item.setNumber(currency.getNumber());
            pack.addItems(item);
        }
        pack.setType(CurrencyType.CT_装备.getNumber());
        return pack;
    }

    public PackageMessage.Item getItemByDataId(String playerCode, CurrencyType type, int dataId) {
        long number = Currency.number(playerCode, type, dataId, false);
        PackageMessage.Item.Builder item = PackageMessage.Item.newBuilder();
        item.setType(type.getNumber());
        item.setDataId(dataId);
        item.setNumber(number);
        return item.build();
    }

    /**
     * 背包里各个位置最好的装备数据
     */
    public equipdata[] getBestEquipInPack(String playerCode) {
        Collection<Currency> currencies = Item.all(playerCode, CurrencyType.CT_装备).values();
        equipdata[] bestDatas = new equipdata[4];// 背包里最好的装备
        for (Currency currency : currencies) {
            if (currency.getNumber() <= 0) {
                continue;
            }
            equipdata data = DataCenter.getData(currency.getDataId(), equipdata.class);
            if (data == null || data.getPosition() >= 5) {
                continue;
            }

            if (bestDatas[data.getPosition() - 1] == null) {
                bestDatas[data.getPosition() - 1] = data;
                continue;
            }
            if (data.level() > bestDatas[data.getPosition() - 1].level()) {
                bestDatas[data.getPosition() - 1] = data;
            }
        }
        return bestDatas;
    }

    /**
     * 交换代币
     *
     * @param reason
     */
    public Result exchange(String playerCode, Currencies costs, Currencies rewards, CCReason reason) {
        // 检查奖励
        int heroSize = 0;
        for (Currency currency : rewards) {
            if (currency.getType().equals(CurrencyType.CT_武将)) {
                // 预检查数据
                herodata _herodata = DataCenter.getData(currency.getDataId(), herodata.class);
                if (_herodata == null) {
                    return Result.DataError;
                }
                heroSize += currency.getNumber();
            }
        }
        HeroHandle heroHandle = new HeroHandle();
        if (heroSize > 0) {
            if (heroHandle.getHerosSize(playerCode) + heroSize > heroHandle.getUpper(playerCode)) {
                return Result.HeroCountUpper; // 武将数超上限
            }
        }

        // 消费
        try {
            new CurrencyHandle().cost(playerCode, reason, costs);
        } catch (CurrencyNotEnoughException e) {
            return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());
        }

        // 兑换奖励
        new CurrencyHandle().addCurrency(playerCode, reason, rewards);

        return Result.Success;
    }

    // 随机物品===========================================================================

    public Currency randomCurrency(randomdrop data) {
        Collection<Reward> rewards = getReward(data, 1);
        for (Reward reward : rewards) {
            return reward.reward;
        }
        return null;
    }

    public Collection<Currency> randomCurrency(randomdrop data, int size) {
        ArrayList<Currency> currencies = new ArrayList<>();
        Collection<Reward> rewards = getReward(data, size);
        for (Reward reward : rewards) {
            currencies.add(reward.reward);
        }
        return currencies;
    }

    private Collection<Reward> getReward(randomdrop data, int size) {
        ArrayList<Reward> rewards = new ArrayList<>();
        for (int i = 0; i < data.getRewardtype().length; i++) {
            int type = data.getRewardtype()[i];
            int weight = data.getPercent()[i];
            if (type > 0 && weight > 0) {
                Currency reward = Currency.create(data.getRewardtype()[i], data.getRewardid()[i], data.getRewardnum()[i]);
                rewards.add(new Reward(reward, weight));
            }
        }
        return RandomUtility.randomWeight(rewards, new ArrayList<>(), size);
    }

    private class Reward implements Weight {
        Currency reward;
        int weight;

        private Reward(Currency reward, int weight) {
            this.reward = reward;
            this.weight = weight;
        }

        @Override
        public int getWeight() {
            return weight;
        }
    }

}
